#include <SD_MMC.h>
#include "ESP32USBMSC.h"
#include <SPIFFS.h>
#include <driver/sdmmc_host.h>
#include <driver/sdmmc_defs.h>
#include <driver/gpio.h>
#include <OneButton.h>

// SD_MMC 引脚配置
gpio_num_t clk = GPIO_NUM_40;
gpio_num_t cmd = GPIO_NUM_39;
gpio_num_t d0 = GPIO_NUM_41;
gpio_num_t d1 = GPIO_NUM_42;
gpio_num_t d2 = GPIO_NUM_48;
gpio_num_t d3 = GPIO_NUM_38;
bool onebit = false;

// 状态变量
bool needFileTest = false;

// OneButton 按键对象，GPIO0
OneButton button(0, true);

// 文件读写测试函数
void testFileOperations()
{
    const char *testFileName = "/test.txt";
    const char *testContent = "Hello ESP32! This is a test file.";

    Serial.println("\n开始文件操作测试...");

    // 检查 SD 卡状态
    if (!SD_MMC.cardSize())
    {
        Serial.println("错误: SD 卡未就绪!");
        return;
    }

    // 1. 创建并写入文件
    Serial.println("1. 创建测试文件...");
    File testFile = SD_MMC.open(testFileName, FILE_WRITE);
    if (!testFile)
    {
        Serial.println("创建文件失败!");
        return;
    }

    size_t bytesWritten = testFile.print(testContent);
    testFile.close();
    Serial.printf("写入 %d 字节到文件\n", bytesWritten);

    // 等待文件系统同步
    delay(100);

    // 2. 读取文件内容
    Serial.println("\n2. 读取文件内容...");
    testFile = SD_MMC.open(testFileName, FILE_READ);
    if (!testFile)
    {
        Serial.println("打开文件失败!");
        return;
    }

    if (testFile.available())
    {
        String content = testFile.readString();
        testFile.close();
        Serial.printf("文件内容: %s\n", content.c_str());
    }
    else
    {
        Serial.println("文件为空!");
        testFile.close();
    }

    // 等待文件系统同步
    delay(100);

    // 3. 删除文件
    Serial.println("\n3. 删除测试文件...");
    if (SD_MMC.exists(testFileName))
    {
        if (SD_MMC.remove(testFileName))
        {
            Serial.println("文件删除成功");
        }
        else
        {
            Serial.println("文件删除失败!");
        }
    }
    else
    {
        Serial.println("文件不存在!");
    }

    Serial.println("文件操作测试完成\n");
}

// 检查 SD 卡状态

// 挂载状态回调函数
void myMountHandler(bool mounted)
{
    if (mounted)
    {
        Serial.println("----------------------------------------");
        Serial.println("U盘已挂载 - 可以开始访问文件");
        Serial.println("----------------------------------------");
        needFileTest = false;
    }
    else
    {
        Serial.println("----------------------------------------");
        Serial.println("U盘已卸载 - 请安全移除设备");
        Serial.println("----------------------------------------");
        needFileTest = true;
    }
}

void myUsbEventHandler(int32_t event_id, void *event_data)
{
    switch (event_id)
    {
    case ARDUINO_USB_STARTED_EVENT:
        Serial.println("USB 连接");
        break;
    case ARDUINO_USB_STOPPED_EVENT:
        Serial.println("USB 断开");
        break;
    case ARDUINO_USB_SUSPEND_EVENT:
        Serial.printf("USB 挂起: remote_wakeup_en: %u\n", ((arduino_usb_event_data_t *)event_data)->suspend.remote_wakeup_en);
        break;
    case ARDUINO_USB_RESUME_EVENT:
        Serial.println("USB 恢复");
        break;
    default:
        break;
    }
}
void setup()
{
    Serial.begin(115200);
    Serial.println("Starting...");

    // 配置 SDMMC 主机参数
    sdmmc_host_t host = SDMMC_HOST_DEFAULT();
    host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
    host.flags = SDMMC_HOST_FLAG_1BIT | SDMMC_HOST_FLAG_4BIT | SDMMC_HOST_FLAG_8BIT | SDMMC_HOST_FLAG_DDR;
    host.slot = SDMMC_HOST_SLOT_1;

    // 配置 SDMMC 总线参数
    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
    slot_config.width = 4;
    slot_config.clk = clk;
    slot_config.cmd = cmd;
    slot_config.d0 = d0;
    slot_config.d1 = d1;
    slot_config.d2 = d2;
    slot_config.d3 = d3;

    // 初始化 SD_MMC，挂载 SD 卡
    Serial.println("Mounting SDcard");
    SD_MMC.setPins((int)clk, (int)cmd, (int)d0, (int)d1, (int)d2, (int)d3);
    if (!SD_MMC.begin("/sdcard", onebit, false, SDMMC_FREQ_HIGHSPEED))
    {
        Serial.println("SD 卡初始化失败");
        return;
    }

    // 获取并打印 SD 卡信息
    Serial.printf("Card Size: %lluMB\n", SD_MMC.cardSize() / (1024 * 1024));
    Serial.printf("Sector: %u\tCount: %u\n", SD_MMC.sectorSize(), SD_MMC.numSectors());

    // 只需调用 usbMsc.begin，是否挂载由库内部自动判断
    usbMsc.begin(&SD_MMC);

    // 在 setup() 函数中添加回调注册
    usbMsc.registerMountCallback(myMountHandler);
    // 注册 USB 事件回调
    usbMsc.registerUsbEventCallback(myUsbEventHandler);
    Serial.println("Setup completed");
}

void loop()
{
    button.tick(); // 轮询按键

    // 卸载后进行文件测试
    if (needFileTest)
    {
        needFileTest = false; // 清除标志
        testFileOperations();
    }
}